package com.zyht.redis.service;

import java.util.List;
import java.util.Map;
import java.util.Set;

import com.zyht.redis.LPopBakAction;
import com.zyht.redis.RedisCash;

public interface RedisService {

	/**
	 * 将字符串值 value 关联到 key 。
	 * 
	 * @param key
	 * @param value
	 */
	public abstract void set(String key, String value);

	/**
	 * 将字符串值 value 关联到 key 。
	 * 
	 * @param key
	 * @param value
	 */
	public abstract void set(byte[] key, byte[] value);

	/**
	 * 删除
	 * 
	 * @param keys
	 * @return
	 */
	public abstract Long del(String... keys);

	/**
	 * 删除
	 * 
	 * @param keys
	 * @return
	 */
	public abstract Long del(byte[]... keys);

	/**
	 * 获取key
	 */
	public abstract String get(String key);

	/**
	 * 获取key
	 */
	public abstract byte[] get(byte[] key);

	/**
	 * 执行脚本
	 * 
	 * @param script
	 *            脚本
	 * @param resultType
	 *            返回值类型
	 * @param value
	 *            脚本内参数(依照数据顺序KEYS[1],KEYS[2])
	 * @return
	 */
	public abstract <T> T eval(String script, Class<T> resultType,
			String... value);

	/**
	 * 执行脚本
	 * 
	 * @param scriptSha
	 * @param resultType
	 * @param value
	 * @return
	 */
	public abstract <T> T evalSha(String scriptSha, Class<T> resultType,
			String... value);

	/**
	 * list.add
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public abstract Long lPush(String key, String value);
	
	public abstract Long lPush(String key, byte[] value);

	/**
	 * list.addall
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public abstract Long lPush(String key, String... value);

	/**
	 * list.size
	 * 
	 * @param key
	 * @return
	 */
	public abstract Long lLen(String key);
	/**
	 * 根据begin和end获取list 如果begin=0,end=-1获取全部list
	 */
	public abstract List<String> lRange(String key, Long begin, Long end);
	/**
	 * 删除目标redis全部DB缓存
	 */
	public abstract void flushAll();

	/**
	 * 预加载脚本
	 * 
	 * @param script
	 * @return sha值
	 */
	public abstract String scriptLoad(String script);

	public abstract Long lPush(String key, String value, Long seconds);

	/**
	 * key 添加有效时间
	 * 
	 * @param key
	 * @param seconds
	 * @return
	 */
	public abstract Boolean expire(byte[] key, Long seconds);
	
	/**
	 * key 添加有效时间
	 * 
	 * @param key
	 * @param seconds
	 * @return
	 */
	public abstract Boolean expire(String key, Long seconds);

	/**
	 * 判断map中是否存在
	 * 
	 * @param key
	 *            redis 中的 key
	 * @param hKey
	 *            Map 中的key
	 * @return
	 */
	public abstract Boolean hExists(String key, String hKey);

	/**
	 * 获取并移除 队首
	 * 
	 * @param key
	 * @return
	 */
	public abstract String lPop(String key);
	/**
	 * 获取并移除 队尾巴
	 * @author:InkYi
	 * @time:2016年7月26日 - 上午10:15:05
	 * @description:
	 * @param key
	 * @return
	 */
	public abstract String rPop(String key);
	/**
	 * 剪切列表
	 * @author:InkYi
	 * @time:2016年7月26日 - 上午10:32:25
	 * @description:
	 * @param msgKye
	 * @param l
	 * @param m
	 */
	public abstract void lTrim(String key, Long begin, Long end);

	/**
	 * 
	 * 将 key 的值设为 value ，当且仅当 key 不存在。 若给定的 key 已经存在，则 SETNX 不做任何动作。 SETNX 是『SET
	 * if Not eXists』(如果不存在，则 SET)的简写。
	 * 
	 * @param key
	 * @param value
	 * @return 设置成功，返回 1 。设置失败，返回 0 。
	 */
	public Boolean setNX(String key, String value);

	/**
	 * 同{@link #setNX(String, String)}
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public Boolean setNX(byte[] key, byte[] value);

	/**
	 * 
	 * <blockquote>
	 * 
	 * <pre>
	 * KEYS pattern
	 * 
	 * 查找所有符合给定模式 pattern 的 key 。
	 * 
	 * KEYS * 匹配数据库中所有 key 。
	 * KEYS h?llo 匹配 hello ， hallo 和 hxllo 等。
	 * KEYS h*llo 匹配 hllo 和 heeeeello 等。
	 * KEYS h[ae]llo 匹配 hello 和 hallo ，但不匹配 hillo 。
	 * 特殊符号用 \ 隔开
	 * 
	 * KEYS 的速度非常快，但在一个大的数据库中使用它仍然可能造成性能问题，如果你需要从一个数据集中查找特定的 key ，你最好还是用 Redis 的集合结构(set)来代替。
	 * </pre>
	 * 
	 * </blockquote>
	 * 
	 * @param patternKey
	 * @return HashSet
	 */
	public Set<String> keys(String patternKey);

	/**
	 * 同步方法处理 <blockquote>
	 * 
	 * <pre>
	 * 订阅一个或多个符合给定模式的频道。
	 * 每个模式以 * 作为匹配符，比如 it* 匹配所有以 it 开头的频道( it.news 、 it.blog 、 it.tweets 等等)， news.* 匹配所有以 news. 开头的频道( news.it 、 news.global.today 等等)，诸如此类。
	 * </pre>
	 * 
	 * </blockquote>
	 * 
	 * @param redisMsgListener
	 * @param patternKeys
	 */
	public void pSubscribe(RedisMsgListener redisMsgListener,
			String... pMsgKeys);

	/**
	 * 
	 * <blockquote>
	 * 
	 * <pre>
	 * 发布消息
	 * </pre>
	 * 
	 * </blockquote>
	 * 
	 * @param msgKey
	 * @param msg
	 * @return
	 */
	public Long publish(String msgKey, String msg);

	/**
	 * 乐观锁更新redis,继承有效期;
	 * <blockquote>
	 * </blockquote>
	 * @param key
	 * @param newValue
	 * @param oldValue
	 * @return 有且仅有更新成功返回true
	 */
	boolean setByLock(String key, String newValue, String oldValue);

	/**
	 * 添加缓存
	 * <blockquote>
	 * <pre>
	 * 
	 * </pre>
	 * </blockquote>
	 * @param cash
	 * @return
	 */
	public <T> T getCash(RedisCash<T> cash);

	/**
	 * 将哈希表 key 中的域 field 的值设为 value 。
如果 key 不存在，一个新的哈希表被创建并进行 HSET 操作。
如果域 field 已经存在于哈希表中，旧值将被覆盖。
	 * @param key
	 * @param field
	 * @param value
	 * @return
	 */
	public abstract Boolean hSet(String key, String field, String value);

	/**
	 * 删除哈希表 key 中的一个或多个指定域，不存在的域将被忽略。
	 * @param key
	 * @param field
	 * @return
	 */
	public abstract Long hDel(String key, String... field);

	/**
	 * 保护队列, 并处理
	 * @param key
	 * @param action
	 * @return
	 */
	public Boolean lPopBak(String key, LPopBakAction action);

	/**
	 * 查看KEY是否存在 
	 * @author:InkYi
	 * @time:2016年6月12日 - 下午12:19:13
	 * @description:
	 * @param key
	 * @return 
	 */
	public abstract boolean exists(String key);
	
	public abstract boolean exists(byte[] key);

	void hMSet(String key,Map<String, String> map);
	
	/**
	 * 返回哈希表 key 中给定域 field 的值。
	 * @param key
	 * @param field
	 * @return
	 */
	String hGet(String key, String field);
	
	byte[] hGet(byte[] key, byte[] field);

	/**
	 * 返回哈希表 key 中，所有的域和值。
	 * @param key
	 * @return
	 */
	Map<String, String> hGetAll(String key);
	/**
	 * 获取hash对应field的value
	 */
	public abstract List<String> hMGet(String key, String... fields);
	/**
	 * 移除等于value的元素，
	 * @description:
	 * 当count>0时，从表头开始查找，移除count个,
	 * 当count=0时，从表头开始查找，移除所有等于value的,
	 * 当count<0时，从表尾开始查找，移除|count|个.
	 */
	public abstract Long lRem(String key, Long count, String value);
	/**
	 * 自增value
	 * @author:InkYi
	 * @time:2016年7月26日 - 上午9:12:33
	 * @description:
	 * @param key
	 * @return
	 */
	public abstract Long incr(String key);
	/**
	 * hash中的自增
	 * @author:InkYi
	 * @time:2016年7月28日 - 上午10:57:21
	 * @description:
	 * @param key
	 * @param field
	 * @param delta
	 * @return
	 */
	Long hIncrBy(String key, String field, Long delta);

	Long hLen(byte[] key);

	Boolean hExists(byte[] key, byte[] field);

	Boolean hSet(byte[] key, byte[] field, byte[] value);

	Long hDel(byte[] key, byte[]... fields);

	Set<byte[]> hKeys(byte[] key);

	List<byte[]> hVals(byte[] key);
	
	/**
	 * 创建并添加时间
	 * @param key
	 * @param seconds
	 * @param value
	 */
	void setEx(String key, long seconds, String value);

	void setEx(byte[] key, long seconds, byte[] value);

}